package com.levi.listener;

import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.levi.pojo.TrancationLog;
import com.levi.service.OrderService;
import com.levi.service.TrancationLogService;
import com.levi.vo.OrderDto;
import lombok.extern.slf4j.Slf4j;
import org.apache.rocketmq.client.producer.LocalTransactionState;
import org.apache.rocketmq.client.producer.TransactionListener;
import org.apache.rocketmq.common.message.Message;
import org.apache.rocketmq.common.message.MessageExt;
import org.apache.rocketmq.spring.annotation.RocketMQTransactionListener;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;

/**
 * @author shentong
 * @since 2022/6/9 8:17 PM
 */
@Component
public class TransactionMsgListener implements TransactionListener {

    @Autowired
    private OrderService orderService;

    @Autowired
    private TrancationLogService trancationLogService;

    /**
     * half  message发送成功之后 开始执行本地事务
     * @param message
     * @param o
     * @return
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public LocalTransactionState executeLocalTransaction(Message message, Object o) {
        LocalTransactionState state;
        try {
            String msg = new String(message.getBody());
            String transactionId = message.getTransactionId();
            OrderDto orderDto = JSONObject.parseObject(msg, OrderDto.class);
            boolean result = orderService.createOrder(orderDto, transactionId);
            if (result){
                state = LocalTransactionState.COMMIT_MESSAGE;
            }else {
                state = LocalTransactionState.ROLLBACK_MESSAGE;
            }
        }catch (Exception e){
//            log.error(e.getMessage());
            state = LocalTransactionState.UNKNOW;
        }

        return state;
    }

    /**
     * 返回 UNKNOW 之后执行本地事务回查 ，可以设置回查频率和最大回查次数
     * @param messageExt
     * @return
     */
    @Override
    public LocalTransactionState checkLocalTransaction(MessageExt messageExt) {
        LocalTransactionState state;
        String transactionId = messageExt.getTransactionId();
        LambdaQueryWrapper<TrancationLog> ew = new LambdaQueryWrapper<>();
        ew.eq(TrancationLog::getId, transactionId);
        TrancationLog trancationLog = trancationLogService.getOne(ew);
        if (null == trancationLog) {
            state = LocalTransactionState.UNKNOW;
        }else {
            state = LocalTransactionState.COMMIT_MESSAGE;
        }
        return state;
    }
}
